package cn.getech.data.metadata.controller.module;

import cn.getech.data.intelligence.common.exception.RRException;
import cn.getech.data.intelligence.common.validator.ValidatorUtils;
import cn.getech.data.metadata.api.gateway.model.dto.CollectionSetting;
import cn.getech.data.metadata.entity.CollectionSystemModuleEntity;
import cn.getech.data.metadata.model.excel.ExcelError;
import cn.getech.data.metadata.service.CollectionSystemModuleService;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class ModuleListener extends AnalysisEventListener<CollectionModuleExcel> {
    private Logger log= LoggerFactory.getLogger(ModuleListener.class);
    private List<CollectionModuleExcel> list = new ArrayList<>();
    private CollectionSystemModuleService moduleService;

    private JSONObject data;
    private List<ExcelError> errorList = Lists.newArrayList();
    private Long userId;
    private  Integer tenantId;

    public ModuleListener(CollectionSystemModuleService moduleService, JSONObject res, Long userId, Integer tenantId) {
        this.data = res;
        this.moduleService = moduleService;
        this.userId=userId;
        this.tenantId=tenantId;
    }

    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        Field[] fields = CollectionModuleExcel.class.getDeclaredFields();
        for (Integer integer : headMap.keySet()) {
            Field field = fields[integer];
            ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
            if (excelProperty != null) {
                if (!excelProperty.value()[0].equals(headMap.get(integer).trim())) {
                    throw new RRException("excel模板内容格式错误");
                }
            }
        }
    }
    @Override
    public void invoke(CollectionModuleExcel data, AnalysisContext context) {
            ReadRowHolder readRowHolder = context.readRowHolder();
            Integer rowIndex = readRowHolder.getRowIndex();
            ExcelError errorDTO = new ExcelError();
            errorDTO.setRowIndex(rowIndex + 1);
            try {
                ValidatorUtils.validateEntity(data);
                String errorField = data.validateValue();
                if (StringUtils.isNotEmpty(errorField)) {
                    errorDTO.setErrMsg("第" + errorDTO.getRowIndex() + "行,"+errorField);
                    errorList.add(errorDTO);
                } else {
                    list.add(data);
                }
            } catch (RRException e) {
                errorDTO.setErrMsg("第" + errorDTO.getRowIndex() + "行," + e.getMsg());
                errorList.add(errorDTO);
            }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        if (CollectionUtil.isNotEmpty(errorList)) {
            List<String> msg = errorList.stream()
                    .map(ExcelError::getErrMsg).collect(Collectors.toList());
            data.put("error_log", String.join("\n", msg));
        } else if (CollectionUtil.isEmpty(list)) {
            data.put("error_log", "文件内容为空");
        } else{
            try {
                saveModule();
            } catch (Exception e) {
                data.put("error_log", e.getMessage());
                log.error("目录导入失败",e);
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveModule(){
        Date now=new Date();
        List<CollectionSetting> configList = moduleService.selectConfigList(tenantId);
        Integer treeLevelMax=2;
        if (CollectionUtil.isNotEmpty(configList)) {
            CollectionSetting config = configList.get(0);
            treeLevelMax= config.getTreeLevelMax();

        }
        for (CollectionModuleExcel module : list) {
            if (StringUtils.isNotEmpty(module.getFirst())) {
                CollectionSystemModuleEntity first=new CollectionSystemModuleEntity();
                first.setParentId(0);
                first.setSmType(1);
                first.setSmName(module.getFirst());
                first.setTenantId(tenantId);
                first.setCreatePer(userId);
                first.setUpdatePer(userId);
                first.setUpdateTime(now);
                first.setCreateTime(now);
                moduleService.saveOrUpdateModule(first);
                Integer parentId = first.getSmId();
                if (StringUtils.isNotEmpty(module.getSecond())) {
                    first.setSmName(module.getSecond());
                    first.setSmId(null);
                    first.setParentId(parentId);
                    first.setSmType(2);
                    if (first.getSmType() > treeLevelMax) {
                        throw new RRException("所属树目录层级超过设置数" + treeLevelMax);
                    }
                    moduleService.saveOrUpdateModule(first);
                    parentId = first.getSmId();
                    if (StringUtils.isNotEmpty(module.getThird())) {
                        first.setSmName(module.getThird());
                        first.setSmId(null);
                        first.setParentId(parentId);
                        first.setSmType(3);
                        if (first.getSmType() > treeLevelMax) {
                            throw new RRException("所属树目录层级超过设置数" + treeLevelMax);
                        }
                        moduleService.saveOrUpdateModule(first);
                        parentId = first.getSmId();
                        if (StringUtils.isNotEmpty(module.getFourth())) {
                            first.setSmName(module.getFourth());
                            first.setSmId(null);
                            first.setParentId(parentId);
                            first.setSmType(4);
                            if (first.getSmType() > treeLevelMax) {
                                throw new RRException("所属树目录层级超过设置数" + treeLevelMax);
                            }
                            moduleService.saveOrUpdateModule(first);
                            parentId = first.getSmId();
                            if (StringUtils.isNotEmpty(module.getFifth())) {
                                first.setSmName(module.getFifth());
                                first.setSmId(null);
                                first.setParentId(parentId);
                                first.setSmType(5);
                                if (first.getSmType() > treeLevelMax) {
                                    throw new RRException("所属树目录层级超过设置数" + treeLevelMax);
                                }
                                moduleService.saveOrUpdateModule(first);
                                parentId = first.getSmId();
                                if (StringUtils.isNotEmpty(module.getSixth())) {
                                    first.setSmName(module.getSixth());
                                    first.setSmId(null);
                                    first.setParentId(parentId);
                                    first.setSmType(6);
                                    if (first.getSmType() > treeLevelMax) {
                                        throw new RRException("所属树目录层级超过设置数" + treeLevelMax);
                                    }
                                    moduleService.saveOrUpdateModule(first);
                                    parentId = first.getSmId();
                                    if (StringUtils.isNotEmpty(module.getSeventh())) {
                                        first.setSmName(module.getSeventh());
                                        first.setSmId(null);
                                        first.setParentId(parentId);
                                        first.setSmType(7);
                                        if (first.getSmType() > treeLevelMax) {
                                            throw new RRException("所属树目录层级超过设置数" + treeLevelMax);
                                        }
                                        moduleService.saveOrUpdateModule(first);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

